package com.ganlucode.sipmock.gb28181.sdp.parser;

import com.ganlucode.sipmock.gb28181.sdp.SDPGBConstants;
import gov.nist.core.InternalErrorHandler;
import gov.nist.core.PackageNames;
import gov.nist.javax.sdp.parser.Lexer;
import gov.nist.javax.sdp.parser.SDPParser;

import java.lang.reflect.Constructor;
import java.text.ParseException;
import java.util.Hashtable;

/**
 * 重写Sip库ParserFactory
 * @see gov.nist.javax.sdp.parser.ParserFactory
 * @author GanLu
 * @date 2020-05-28 10:18
 */
public class ParserFactoryGB28181 {
    private static Hashtable parserTable;
    private static Class[] constructorArgs;
    private static final String packageName =
            PackageNames.SDP_PACKAGE + ".parser";

    private static Class getParser(String parserClass) {
        try {
            return Class.forName(packageName + "." + parserClass);
        } catch (ClassNotFoundException ex) {
            System.out.println("Could not find class");
            ex.printStackTrace();
            System.exit(0);
            // dummy
            return null;
        }
    }

    private static Class getCustomerParser(String parserClass) {
        try {
            return Class.forName(SDPGBConstants.SDP_FIELD_PACKAGE + "." + parserClass);
        } catch (ClassNotFoundException ex) {
            System.out.println("Could not find class");
            ex.printStackTrace();
            System.exit(0);
            // dummy
            return null;
        }
    }

    static {
        constructorArgs = new Class[1];
        constructorArgs[0] = String.class;
        parserTable = new Hashtable();
        parserTable.put("a", getParser("AttributeFieldParser"));
        parserTable.put("b", getParser("BandwidthFieldParser"));
        parserTable.put("c", getParser("ConnectionFieldParser"));
        parserTable.put("e", getParser("EmailFieldParser"));
        parserTable.put("i", getParser("InformationFieldParser"));
        parserTable.put("k", getParser("KeyFieldParser"));
        parserTable.put("m", getParser("MediaFieldParser"));
        parserTable.put("o", getParser("OriginFieldParser"));
        parserTable.put("p", getParser("PhoneFieldParser"));
        parserTable.put("v", getParser("ProtoVersionFieldParser"));
        parserTable.put("r", getParser("RepeatFieldParser"));
        parserTable.put("s", getParser("SessionNameFieldParser"));
        parserTable.put("t", getParser("TimeFieldParser"));
        parserTable.put("u", getParser("URIFieldParser"));
        parserTable.put("z", getParser("ZoneFieldParser"));
        //GB28181添加字段
        parserTable.put("y", getCustomerParser("SsrcFieldParser"));
    }

    public static SDPParser createParser(String field) throws ParseException {
        String fieldName = Lexer.getFieldName(field);
        //暂时不解析f字段
        if ("f".equalsIgnoreCase(fieldName)) {
            return null;
        }
        if (fieldName == null) {
            return null;
        }
        Class parserClass = (Class) parserTable.get(fieldName.toLowerCase());

        if (parserClass != null) {
            try {

                Constructor cons = parserClass.getConstructor(constructorArgs);
                Object[] args = new Object[1];
                args[0] = field;
                SDPParser retval = (SDPParser) cons.newInstance(args);
                return retval;

            } catch (Exception ex) {
                InternalErrorHandler.handleException(ex);
                // to placate the compiler.
                return null;
            }
        } else {
            throw new ParseException(
                    "Could not find parser for " + fieldName,
                    0);
        }
    }
}
